#============================================
# ●django中间件
# 首先django自带七个中间件，每个中间件都有各自对应的功能
# 并且django还支持程序员自定义中间件
# 你在用django开发项目的项目的时候，只要是涉及到全局相关的功能都可以使用中间件
# 方便的完成
# 。全局用户身份校验
# 。全局用户权限校验
# 。全局访问频率校验
# .....
#============================================
# django中间件是django的门户
# 1.请求来的时候需要先经过中间件才能到达真正的dj ango后端
# 2.响应走的时候最后也需要经过中间件才能发送出去
 
#  7个中间件
#  MIDDLEWARE = [
#     'django.middleware.security.SecurityMiddleware',
#     'django.contrib.sessions.middleware.SessionMiddleware',
#     'django.middleware.common.CommonMiddleware',
#     'django.middleware.csrf.CsrfViewMiddleware',
#     'django.contrib.auth.middleware.AuthenticationMiddleware',
#     'django.contrib.messages.middleware.MessageMiddleware',
#     'django.middleware.clickjacking.XFrameOptionsMiddleware',
# ]
#============================================
# django支持程序员自定义中间件并且暴露给程序员五个可以自定义的方法
# 1.必须掌握
# process_request
# process_response
# 2.了解即可
# process_view
# process_template_response
# process_exception

# 如何自定义中间件
# 1.在项目名或者应用名下创建-个任意名称的文件夹
# 2.在该文件夹内创建-个任意名称的py文件
# 3.在该py文件内需要书写类(这个类必须继承MiddlewareMixin)
# 然后在这个类里面就可以自定义五个方法了
# (这五个方法并不是全部都需要书写，用几个写几个)
# 4.需要将类的路径以字符串的形式注册到配置文件中才能生效
#  MIDDLEWARE = [
#     'django.middleware.security.SecurityMiddleware',
#     'django.contrib.sessions.middleware.SessionMiddleware',
#     'django.middleware.common.CommonMiddleware',
#     'django.middleware.csrf.CsrfViewMiddleware',
#     'django.contrib.auth.middleware.AuthenticationMiddleware',
#     'django.contrib.messages.middleware.MessageMiddleware',
#     'django.middleware.clickjacking.XFrameOptionsMiddleware',
#      你自己写的中间件的路径1' ,
#      你自己写的中间件的路径2',
#      你自己写的中间件的路径3'，
# ]
# 列子
# class mymiddkeware(MiddlewareMixin):
#     def process_request(self,request):
#         print('.....')
#         return Httpresponse('111111')


# app01.mymiddleware.mymiddleware

# 1.必须掌握
# process_request
# 1.请求来的时候需要经过每一个中间件 里面的process_ request方法
# 结果的顺序是按照配置文件中注册的中间件从上往下的顺序依次执行
# 2.如果中间件里面没有定义该方法，那么直接跳过执行下一个中间件
# 3.如果该方法返回了HttpResponse对象，那么请求将不再继续往后执行
# 而是直接原路返回(校验失败不允许访问...)
# process_request方法就是用来做全局相关的所有限制功能
  
# process_response
# 1.响应走的时候需要结果每一个中间件里面的process_ response方法
# 该方法有两个额外的参数request, response
# 2.该方法必须返回一-个HttpResponse对象
# 1.默认返回的就是形参response
# 2.你也可以自己返回自己的
# 3.顺序是按照配置文件中注册了的中间件从下往.上依次经过
# 如果你没有定义的话直接跳过执行下一个

# 研究如果在第-个process_request方法就已经返回了HttpResponse对象，那么响应走
# 的时候是经过所有的中间件里面的process_response还是 有其他情况
# 是其他情况
# 就是会直接走同级别的process_reponse返回

# flask框架也有一个中间件但是它的规律
# 只要返回数据了就必须经过所有中间件里面的类似于process_ reponse方法




# process_ view
# 路由匹配成功之后执行视图函数之前，会自动执行中间件里面的方法
# 顺序是按照配置文件中注册的中间件从上往下的顺序依次执行
# process_ template_ response
# 返回的HttpResponse对象有render属性的时候才会触发
# 顺序是按照配置文件中注册了的中间件从下往上依次经过
# process_ exception
# 当视图函数中出现异常的情况下触发
# 顺序是按照配置文件中注册了的中间件从下往上依次经过
#============================================
# csrf跨站请求伪造
# 钓鱼网站
# 我搭建一个跟正规网站一模一样的界面(中国银行)
# 用户不小心进入到了我们的网站，用户给某个人打钱
# 打钱的操作确确实实是提交给了中国银行的系统，用户的钱也确确实实减少了
# 但是唯一不同的时候打钱的账户不适用户想要打的账户变成了一个莫名其妙的账户
# 大学英语四六级

# 考之前需要学生自己网站登陆缴费
# 内部本质
# 我们在钓鱼网站的页面针对对方账户只给用户提供一个没有name属性的普通input框
# 然后我们在内部隐藏一个已经写 好name和value的input框
# 如何规避上述问题
# csrf跨站请求伪造校验
# 网站在给用户返回一个具有提交数据功能页面的时候会给这个页面加一个唯一标识
# 当这个页面朝后端发送post请求的时候我的后端会先校验唯一标识， 如果唯一标识不对直
# 接拒绝(403 forbbiden) 如果成功则正常执行

# 取消此功能方法
# 前端
# post请求
# 加上模板语法{%  csrf_token  %}

# ajax请求
# //第一种利用标签查找获取页面上的随机字符串
# {#data :{"username": 'jason' , ' csrfmiddLewaretoken' :$(' [name=csrfmiddLewaretoken]').vaL()},#} 
# //第二种利用模版语法提供的快捷书写
# {#data: {"username": 'jason' , ' csrfmiddLewaretoken':'{{ csrf token }}'},#}
# //第三种通用方式
# <script src="{% static ' js/mysetup.js' %}"></ script>  导用js代码，自动校验

# 后端
# from django. views . decorators.csrf import csrf_protect,csrf_ exempt
# from django. utils . decorators import method_ decorator

# csrf_ protect
# 需要校验
# 针对csrf_ protect符合 我们之前所学的装饰器的三种玩法(CBV)

# csrf_ exempt
# 忽视校验
# 针对csrf_ exempt 只能给dispatch方法加才有效method_decorator(语法糖,name = 'post')

# @语法糖使用
#============================================
# 补充知识点
# import importLib
# res=' myfile.b'
# ret = importli. import_ moduLe(res) # from myfile import b
# #该方法最小只能到py文件名
# print(ret)


# 主要思想
# def send_all(connect):
#     for path_str in setting.LIST:
#         moudel_path,class_name = path_str.rstplit('.',max=1)
#         moule = importlib.import_module(moudel_path)
#         cls = getattr(moule,class_name)
#         obj = cls()
#         obj.send(connect)
#功能的插拔式设计
# 1.配置文件注册功能
# 2. importlib模块
# 3.字符串切割split
# 4.反射
# 5.面向对象及鸭子类型
#一定要总结吸收该思想
#============================================